/**
 * @file JdTools.h
 *
 * Narzędzia do przeliczania daty i JD - nagłówek.
 *
 * @author Zbigniew Siciarz
 * @date 2009
 * @version 2.0.0
 * @since 2.0.0
 */

#ifndef JDTOOLS_H_
#define JDTOOLS_H_

#include <QDateTime>
#include <QTime>
#include <QString>

/**
 * Zestaw narzędzi do przeliczania daty na JD i odwrotnie.
 */
class JdTools
{
public:
    /**
     * Typ zwracanego JD - w praktyce służy tylko jako sugestia, które
     * przeładowanie funkcji wybrać.
     */
    enum JDFormat {AsString};

    static double currentJd()
    {
        return dateToJd(QDateTime::currentDateTime());
    }

    /**
     * Zwraca datę (i czas) przekonwertowane do JD.
     *
     * Data jest normalizowana do UTC.
     *
     * @param date obiekt daty i czasu
     * @return JD jako liczba zmiennoprzecinkowa
     */
    static double dateToJd(const QDateTime& date)
    {
        QDateTime dateUtc = date.toUTC();
        int jdDate = dateUtc.date().toJulianDay();
        int secsFromNoon = QTime(12, 0, 0).secsTo(dateUtc.time());
        return static_cast<double>(jdDate) + secsFromNoon / 86400.0;
    }

    /**
     * Zwraca datę (i czas) przekonwertowane do JD, w formie łańcucha znaków.
     *
     * Data jest normalizowana do UTC.
     *
     * @param date obiekt daty i czasu
     * @return JD jako ciąg znaków
     */
    static QString dateToJd(const QDateTime& date, JDFormat /* format */)
    {
        return QString::number(JdTools::dateToJd(date), 'f', 4);
    }

    /**
     * Zwraca datę i czas odpowiadające podanemu JD.
     *
     * @param jd wartość JD jako liczba zmiennoprzecinkowa
     * @return data i czas UTC
     */
    static QDateTime jdToDate(double jd)
    {
        int intJd = static_cast<int>(jd);
        QDate date = QDate::fromJulianDay(intJd);
        QTime time = QTime(12, 0, 0).addSecs(
                static_cast<int>((jd - intJd) * 86400));
        return QDateTime(date, time, Qt::UTC);
    }

    /**
     * Zwraca datę i czas odpowiadające podanemu JD.
     *
     * Jeśli podany ciąg znaków nie jest poprawną liczbą zmiennoprzecinkową,
     * to zwracana data odpowiada JD=0.0!
     *
     * @param jd wartość JD jako łańcuch znaków
     * @return data i czas UTC
     */
    static QDateTime jdToDate(QString jd)
    {
        bool ok;
        double doubleJd = jd.toDouble(&ok);

        return JdTools::jdToDate(ok ? doubleJd : 0.0);
    }
};

#endif /* JDTOOLS_H_ */
